<?php

namespace common\helpers;

use Yii;

/**
 * Description of PinyinHelper
 *
 * @author emhome<emhome@163.com>
 * @since 1.0
 */
class PinyinHelper {

    /**
     * @var boolean 是否增加备注信息
     */
    public static $dataAlias = '@common/data/pinyin';

    /**
     * 中文转拼音
     * @param string $words 待转义字符串
     * @param bool $first 首字母
     * @param bool $upper 首字母大写
     * @param bool $initial 仅第一字符首字母 ($ret_format 返回格式 [all:全拼音|first:首字母|one:仅第一字符首字母])
     * @param string $placeholder 无法识别的字符占位符
     * @param string $safeRegx 允许的非中文字符（安全匹配）
     * @return string
     */
    public static function translate($words, $first = false, $upper = true, $initial = false, $placeholder = '', $safeRegx = '/[a-zA-Z\d ]/') {
        static $pinyins = null;
        if (null === $pinyins) {
            $pinyins = static::buildWordsLibary();
        }
        $str = trim($words);
        $len = mb_strlen($str, 'UTF-8');
        $rs = '';
        for ($i = 0; $i < $len; $i++) {
            $chr = mb_substr($str, $i, 1, 'UTF-8');
            $asc = ord($chr);
            if ($asc < 0x80) {
                // 0-127
                if ($safeRegx && preg_match($safeRegx, $chr)) {
                    // 用参数控制正则
                    $rs .= $chr; // 0-9 a-z A-Z 空格
                } else {
                    // 其他字符用填充符代替
                    $rs .= $placeholder;
                }
            } else {
                // 128-255
                if (isset($pinyins[$chr])) {
                    $rs .= $first ? $pinyins[$chr][0] : ($pinyins[$chr] . ' ');
                } else {
                    $rs .= $placeholder;
                }
            }
            if ($initial && '' !== $rs) {
                $rs = $rs[0];
                break;
            }
        }
        $phonetic = trim($rs);
        if ($upper) {
            return ucwords($phonetic);
        }
        return $phonetic;
    }

    /**
     * Loads the message translation for the specified language and category or returns null if file doesn't exist.
     *
     * @param string $name path to message file
     * @return array|null|string array of messages or null if file not found
     */
    public static function loadWordsLibaryFromFile($name = null) {
        if (!$name) {
            $name = 'rareWords.txt';
        }
        $ext = pathinfo($name, PATHINFO_EXTENSION);
        $path = Yii::getAlias(static::$dataAlias . '/' . $name);
        if (!file_exists($path)) {
            return null;
        }
        if ($ext == 'php') {
            return require $path;
        }
        $data = file_get_contents($path);
        if ($ext == 'json') {
            return Json::decode($data);
        }
        return $data;
    }

    public static function buildWordsLibary() {
        $data = static::loadWordsLibaryFromFile();
        $rows = array_filter(explode('|', $data));
        $pinyins = [];
        foreach ($rows as $v) {
            list($py, $vals) = explode(':', $v);
            $chars = explode(',', $vals);
            foreach ($chars as $char) {
                $pinyins[$char] = $py;
            }
        }
        return $pinyins;
    }

    /**
     * PHP 汉字转拼音 [包含20902个基本汉字+5059生僻字]
     * @author 楼教主(cik520@qq.com)
     * @version v1.2
     * @note 请开启 mb_string 扩展
     */
    protected static function debuger() {
        $subject = '|nin:囜,您,拰,脌|kun:困,壸,壼,裩,褌,醌,錕,锟|qun:裙,裠,輑,逡,㪊,㿏,囜,䭽|ri:囸,日,釰,鈤,馹,驲,䒤|lve:圙,擽,畧,稤,稥,䤣|zhui:坠,䕅,䖣|zang:塟,䶊';
        $end = '囜';
        preg_match_all('/(?<=\|)([a-zA-Z]+):(?!\|).*?' . $end . '/', $subject, $matches);
    }

    /**
     * 汉字转拼音函数（效率低，即将废弃）
     * @param string $s 汉字字符串
     * @param bool $quanpin 是否全拼
     * @param bool $daxie 首字母是否大写
     * @return string
     */
    public static function transform($s, $quanpin = true, $daxie = true, $split = '') {
        $s = preg_replace("/\s/is", "_", $s);
        $s = preg_replace("/(|\~|\`|\!|\@|\#|\$|\%|\^|\&|\*|\(|\)|\-|\+|\=|\{|\}|\[|\]|\||\\|\:|\;|\"|\'|\<|\,|\>|\.|\?|\/)/is", "", $s);
        $i = 0;
        $py = [];
        $wordLibary = static::loadWordsLibaryFromFile('data.php');
        // 加入这一句，自动识别UTF-8
        if (strlen("拼音") > 4) {
            $s = iconv('UTF-8', 'GBK', $s);
        }
        if ($quanpin) {
            // 全拼
            for ($i = 0; $i < strlen($s); $i++) {
                if (ord($s[$i]) > 128) {
                    $charCode = ord($s[$i]) + ord($s[$i + 1]) * 256;
                    $char = '';
                    foreach ($wordLibary as $_pinyin => $_codes) {
                        if (in_array($charCode, $_codes)) {
                            $char = $_pinyin;
                            break;
                        }
                    }
                    $py[] = $char;
                    $i++;
                } else {
                    $py[] = $s[$i];
                }
            }
        } else {
            // 首字母
            for ($i = 0; $i < strlen($s); $i++) {
                if (ord($s[$i]) > 128) {
                    $charCode = ord($s[$i]) + ord($s[$i + 1]) * 256;
                    $char = static::asciiToPinyin($charCode);
                    $py[] = $char[0];
                    $i++;
                } else {
                    $py[] = $s[$i];
                }
            }
        }
        if ($split !== false) {
            $string = implode($split, $py);
            // 判断是否输出小写字符
            return ($daxie == true ? $string : strtolower($string));
        }
        return $py;
    }

    public static function asciiToPinyin($a) {
        $py = static::loadWordsLibaryFromFile('data.php');
        foreach ($py as $p) {
            if (array_search($a, $p) !== false) {
                return key($py);
            }
            next($py);
        }
    }

}
